perm filename IMAGE.SAI[SYS,HE] blob sn#056326 filedate 1973-08-02 generic text, type T, neo UTF8
00100	
00200	
00300	
00400	
00500	
00600	PROCEDURE DIS_VERT(SHORT INTEGER J);
00700	
00800	⊃ Here we display the lines forming a vertex with arrows
00900		pointing toward the vertex;
01000	
01100	BEGIN
01200	SHORT INTEGER I,K;
01300	SHORT REAL XC,YC,DX,DY,XV,YV,DELX,DELY,SIGX,SIGY;
01400		XV←VERTEX[J,1];
01500		YV←VERTEX[J,2];
01600		DPYSET(BUF);
01700		BOUNDARY(X1,Y2,X2,Y1);
01800		FOR I←1 STEP 1 UNTIL VERTEX[J,3] DO
01900		BEGIN
02000			K←VERTEX[J,3+I];
02100			LINE_DISP(K);
02200		XC←(HUMPS[K,FPOINT+1]+HUMPS[K,HUMPS[K,6]+1])/2.;
02300		YC←(HUMPS[K,FPOINT+2]+HUMPS[K,HUMPS[K,6]+2])/2.;
02400			DELX←XV-XC;
02500			DELY←YV-YC;
02600			SIGX←SIGN(DELX);
02700			SIGY←SIGN(DELY);
02800			DX←SIGX*ABS(HUMPS[K,SINTHETA]);
02900			DY←SIGY*ABS(HUMPS[K,COSTHETA]);
03000			IF ABS(DX)>0.5 THEN ARROW(XC,YC-2,DX,DY)
03100			ELSE ARROW(XC-3,YC,DX,DY);
03200			AIVECT(-400, 460-60*I);
03300			DPYSST(" DX="&CVG(DX)&"  DY="&CVG(DY));
03400			AIVECT(-400,430-60*I);
03500			DPYSST(" XV - XC="&CVG(DELX)&"  YV - YC ="&CVG(DELY));
03600		END;
03700		DPYOUT(1);
03800	END;
03900	
     

00100	PROCEDURE FINDIMAG(INTEGER MODLINES,DIREC,SEARCH;
00200				REAL TOLER;REAL ARRAY CORNMOD);
00300	
00400	⊃ Here we try to find a line or corner in the window selected
00500		by SRCHIMAG;
00600	
00700	  BEGIN "FINDIMAG"
00800		SHORT INTEGER N2FOUND,N3FOUND;
00900	 	SHORT REAL XX,YY,X,Y;
01000	
01100	
01200	DEFINE TRY(J) = { IF COMPARE(J) THEN 
01300			BEGIN
01400				STORE_CORN(J,MODLINES);
01500				IF ¬WANT_ALL THEN GO TO SUCCESS;
01600			END;        };
01700	
01800	BOOLEAN PROCEDURE FIT(INTEGER N,J);
01900	⊃ Here we compare the edge line "N" with the model line "J";
02000	BEGIN "FIT"
02100	SHORT REAL TEMP;
02200	IF DEB_EYE THEN OUTSTR(" IN FIT --- N="&CVS(N)&"  J="&CVS(J)ACRLF);
02300			IF HUMPS[N,DIRCOS]*CORNMOD[J,COSDIR]
02400			+HUMPS[N,DIRSIN]*CORNMOD[J,SINDIR]<1-TOLER THEN
02500	BEGIN  IF DEB_EYE THEN OUTSTR(" REJECTED BECAUSE OF ANGULAR TOLERANCE
02600	DXL="&CVG(HUMPS[N,DIRSIN])&"  DXM="&CVG(CORNMOD[J,SINDIR])&"
02700	DYL="&CVG(HUMPS[N,DIRCOS])&"  DYM="&CVG(CORNMOD[J,COSDIR])ACRLF);
02800		RETURN(0);   END;
02900			IF DIREC=0∨(J=2∧MODLINES=3) THEN RETURN(-1);
03000			TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
03100			IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
03200			RETURN(-1) ELSE 
03300			BEGIN 
03400				IF DEB_EYE THEN  OUTSTR("REJECTED BECAUSE
03500			WRONG INTENSITY DIRECTION --TEMP="&CVG(TEMP)ACRLF);
03600				RETURN(0); 
03700			END;
03800	END "FIT";
03900	
04000	
04100	BOOLEAN PROCEDURE ABSFIT(INTEGER N,J);
04200	⊃ This is like FIT except we accept either direction for the line;
04300	BEGIN "ABSFIT"
04400	SHORT REAL TEMP;
04500			IF ABS(HUMPS[N,COSTHETA]*CORNMOD[J,COSTHETA]
04600			+HUMPS[N,SINTHETA]*CORNMOD[J,SINTHETA])<1-TOLER THEN
04700			RETURN(0);
04800			IF DIREC=0∨(J=2∧MODLINES=3) THEN RETURN(-1);
04900			TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
05000			IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
05100			RETURN(-1) ELSE RETURN(0);
05200	END "ABSFIT";
     

00100	
00200	
00300	INTEGER PROCEDURE BESTFIT(INTEGER N);
00400	⊃ Here we compare the edge line "N" with the all the model lines;
00500	BEGIN "BFIT"
00600	SHORT REAL TEMP,MAX,MAXNJ;
00700	SHORT INTEGER J,ISAVE;
00800	LABEL LAST,SAVE;
00900		MAX←0; ISAVE←0;
01000	FOR J←1 STEP 1 UNTIL MODLINES DO
01100	BEGIN
01200	IF DEB_EYE THEN OUTSTR(" IN BESTFIT --- N="&CVS(N)&"  MODL="&CVS(J)ACRLF);
01300			IF (MAXNJ←HUMPS[N,DIRCOS]*CORNMOD[J,COSDIR]
01400			+HUMPS[N,DIRSIN]*CORNMOD[J,SINDIR])<1-TOLER THEN
01500			BEGIN  
01600	IF DEB_EYE THEN OUTSTR(" REJECTED BECAUSE OF ANGULAR TOLERANCE
01700	DXL="&CVG(HUMPS[N,DIRSIN])&"  DXM="&CVG(CORNMOD[J,SINDIR])&"
01800	DYL="&CVG(HUMPS[N,DIRCOS])&"  DYM="&CVG(CORNMOD[J,COSDIR])ACRLF);
01900				GO TO LAST;
02000		             END;
02100			IF DIREC=0∨(J=2∧MODLINES=3) THEN GO TO SAVE;
02200			TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
02300			IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
02400			GO TO SAVE ELSE 
02500			BEGIN 
02600				IF DEB_EYE THEN  OUTSTR("REJECTED BECAUSE
02700			WRONG INTENSITY DIRECTION --TEMP="&CVG(TEMP)ACRLF);
02800				GO TO LAST;
02900			END;
03000	SAVE:		IF MAXNJ> MAX THEN
03100			BEGIN
03200				MAX←MAXNJ;
03300				ISAVE←J;
03400			END;
03500	LAST:  END;
03600		RETURN(ISAVE);
03700	
03800	END "BFIT";
03900	
04000	
     

00100	
00200	
00300	
00400	INTEGER PROCEDURE ROUGH_COMPARE;
00500	⊃ Here we throw out lines which do not fit any model line.
00600		No comparison of the direction of the line with respect
00700		to vertex is made;
00800	
00900	BEGIN "COMP"
01000	SHORT INTEGER N,I,J,JHUMP,NFOUND;
01100	SHORT REAL TEMP;
01200	SHORT INTEGER ARRAY REJ[1:3];
01300	LABEL AFTER, NOFIT, REJECT,FOUND;
01400		NFOUND←0;
01500		FOR N←0 STEP 1 UNTIL NLINES-1 DO
01600		BEGIN "OUTER"
01700		FOR J←1 STEP 1 UNTIL MODLINES DO
01800		BEGIN
01900			IF ABS(HUMPS[N,COSTHETA]*CORNMOD[J,COSTHETA]
02000			+HUMPS[N,SINTHETA]*CORNMOD[J,SINTHETA])<1-TOLER THEN
02100			BEGIN REJ[J]←1; GO TO NOFIT; END;
02200			IF DIREC=0∨(J=2∧MODLINES=3) THEN GO TO FOUND;
02300			TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
02400			IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
02500	FOUND:		BEGIN NFOUND←NFOUND+1; GO TO AFTER; END;
02600			REJ[J]←-1;
02700	NOFIT:	END;
02800	REJECT:	IF DEB_EYE THEN
02900		BEGIN
03000			DPYSET(BUF);
03100			BOUNDARY(X1,Y2,X2,Y1);
03200			LINE_DISP(N);
03300			AIVECT(-400,420);
03400			DPYSST(" THIS LINE REJECTED BECAUSE (");
03500			FOR I←1 STEP 1 UNTIL MODLINES DO
03600			BEGIN
03700				IF REJ[I]>0 THEN
03800				DPYSST(CVS(I)&")  WRONG ANGLE ")
03900				ELSE DPYSST(CVS(I)&")  WRONG INTENSITY DIRECTION");
04000			        AIVECT(-300,420-30*I);
04100			END;
04200			DPYSST(" THETA="& CVG(HUMPS[N,1])
04300	                       &" COSTH="& CVG(HUMPS[N,COSTHETA])
04400	 			&"SINTH="&CVG(HUMPS[N,SINTHETA]));
04500			DPYOUT(1);
04600		END;
04700		JHUMP←HUMPS[NLINES-1,6]+2;
04800		FOR I←1 STEP 1 UNTIL JHUMP DO
04900		HUMPS[N,I]←HUMPS[NLINES-1,I];
05000		NLINES←NLINES-1;
05100		N←N-1;
05200	AFTER:	END "OUTER";
05300		IF DEB_EYE THEN
05400		FOR N←0 STEP 1 UNTIL NLINES-1 DO
05500			OUTSTR(" THETA="& CVG(HUMPS[N,1])
05600	                       &" COSTH="& CVG(HUMPS[N,COSTHETA])
05700	 			&"SINTH="&CVG(HUMPS[N,SINTHETA])ACRLF);
05800		RETURN(NFOUND); ⊃ Return the number of lines that were found;
05900	END "COMP";
06000	
     

00100	
00200	
00300	BOOLEAN PROCEDURE DIR_TEST(SHORT INTEGER NVERT);
00400	
00500	⊃ Here we test each line forming vertex NVERT to see if they
00600		match any model line considering direction with
00700		respect to the vertex;
00800	
00900	BEGIN "DIR"
01000	SHORT INTEGER N,J,I,K,NFOUND;
01100	SHORT REAL TEMP,XB,YB,XF,YF;
01200	SHORT REAL XC,YC,DXL,DYL,DXM,DYM,XV,YV,DELX,DELY,SIGX,SIGY;
01300	BOOLEAN TEST;
01400	SHORT INTEGER ARRAY REJ[1:3];
01500	LABEL AFTER,AFT1, NOFIT, REJECT;
01600		NFOUND←0; TEST←0;
01700		XV←VERTEX[NVERT,1];
01800		YV←VERTEX[NVERT,2];
01900		FOR I←1 STEP 1 UNTIL VERTEX[NVERT,3] DO
02000		BEGIN "OUTER"
02100			N←VERTEX[NVERT,3+I];
02200			IF HUMPS[N,3]≠NVERT∧HUMPS[N,4]≠NVERT∧NVERT≤NVERTEX THEN
02300			BEGIN
02400				IF DIS_EYE THEN OUTSTR(" LINE "&CVS(N)&
02500				"  IS INTERSECTED IN MIDDLE"ACRLF);
02600				GO TO AFTER;
02700			END;
02800			XB←HUMPS[N,FPOINT+1]; XF←HUMPS[N,HUMPS[N,6]+1];
02900			YB←HUMPS[N,FPOINT+2]; YF←HUMPS[N,HUMPS[N,6]+2];
03000			XC←(XB+XF)/2.;  YC←(YB+YF)/2.;
03100			IF (XV-XB)↑2+(YV-YB)↑2>(XV-XF)↑2+(YV-YF)↑2 THEN
03200	⊃ Filling array HUMPS with "VERT_END";
03300			HUMPS[N,VERT_END]←HUMPS[N,6]
03400			ELSE HUMPS[N,VERT_END]←FPOINT;
03500			DELX←XV-XC;
03600			DELY←YV-YC;
03700			SIGX←SIGN(DELX);
03800			SIGY←SIGN(DELY);
03900	⊃ FILLING ARRAY HUMPS WITH "DIRSIN" AND "DIRCOS" WHICH ARE USED
04000		LATER IN "COMPARE" ("FIT" THAT IS);
04100			DXL←HUMPS[N,DIRSIN]←SIGX*ABS(HUMPS[N,SINTHETA]);
04200			DYL←HUMPS[N,DIRCOS]←SIGY*ABS(HUMPS[N,COSTHETA]);
04300		FOR J←1 STEP 1 UNTIL MODLINES DO
04400		BEGIN
04500			DXM←CORNMOD[J,SINDIR];
04600			DYM←CORNMOD[J,COSDIR];
04700	IF DEB_EYE THEN OUTSTR(" LINE "&CVS(N)&" DXL="&CVG(DXL)&" DYL="&CVG(DYL)&"
04800		  MODEL LINE "&CVS(J)&" DXM="&CVG(DXM)&" DYM="&CVG(DYM)ACRLF);
04900	
05000			IF DXL*DXM+DYL*DYM<1-TOLER THEN
05100			BEGIN REJ[J]←1; GO TO NOFIT; END;
05200			IF DIREC=0∨(J=2∧MODLINES=3) THEN GO TO AFTER;
05300			TEMP←ABS(HUMPS[N,1]-CORNMOD[J,8]);
05400			IF TEMP<PIO2∨ABS(TEMP-PIT2)<PIO2 THEN
05500	                GO TO AFTER;
05600			REJ[J]←-1;
05700	NOFIT:	END;
05800	REJECT:	NFOUND←-1;
05900		IF DEB_EYE THEN  ⊃ Tell why each line is rejected and
06000				show line on screen;
06100		BEGIN
06200			DPYSET(BUF);
06300			BOUNDARY(X1,Y2,X2,Y1);
06400			LINE_DISP(N);
06500			AIVECT(-400,420);
06600			DPYSST(" THIS LINE REJECTED BECAUSE (");
06700			FOR K←1 STEP 1 UNTIL MODLINES DO
06800			BEGIN
06900				IF REJ[K]>0 THEN
07000				DPYSST(CVS(K)&")  WRONG ANGULAR DIRECTION 
07100						WITH RESPECT TO VERTEX ")
07200				ELSE DPYSST(CVS(K)&")  WRONG INTENSITY DIRECTION");
07300			        AIVECT(-300,420-30*K);
07400			END;
07500			DPYSST(" THETA="& CVG(HUMPS[N,1])
07600	                       &" COSTH="& CVG(HUMPS[N,COSTHETA])
07700	 			&"SINTH="&CVG(HUMPS[N,SINTHETA]));
07800			DPYOUT(1);
07900		END;
08000		IF NVERT>NVERTEX THEN GO TO AFTER;
08100		⊃ THIS IS USED FOR THE CASE OF TEST-VERTICIES;
08200		VERTEX[NVERT,3+I]←VERTEX[NVERT,VERTEX[NVERT,3]+3];
08300		K←VERTEX[NVERT,3]←VERTEX[NVERT,3]-1;
08400	AFT1:	IF HUMPS[N,3]=NVERT THEN
08500		HUMPS[N,3]←HUMPS[N,13]←HUMPS[N,14]←-1
08600		ELSE IF HUMPS[N,4]=NVERT THEN 
08700		HUMPS[N,4]←HUMPS[N,15]←HUMPS[N,16]←-1;
08800		IF TEST THEN GO TO AFTER;
08900		IF K<2 THEN 
09000		BEGIN
09100			IF NVERT=NVERTEX THEN NVERTEX←NVERTEX-1 ELSE
09200			BEGIN
09300				VERTEX[NVERT,1]←-1000.;
09400				VERTEX[NVERT,2]←-1000.;
09500				VERTEX[NVERT,3]←0;
09600			END;
09700			IF K=0 THEN GO TO AFTER;
09800			N←VERTEX[NVERT,4];
09900			TEST←-1;
10000			GO TO AFT1;
10100		END;
10200		IF I≤VERTEX[NVERT,3] THEN I←I-1;
10300	AFTER:	END "OUTER";
10400		RETURN(NFOUND); ⊃ Return TRUE if you find a line to reject;
10500	END "DIR";
10600	
     

00100	
00200	BOOLEAN PROCEDURE COMPARE(SHORT INTEGER NVERT);
00300	⊃ Here we compare all the model lines with all the lines
00400		forming vertex NVERT. Now the model lines must be
00500		fitted be different lines;
00600	
00700	BEGIN "PARE"
00800	SHORT INTEGER LINE1,LINE2,LINE3,I,K;
00900	LABEL FAIL;
01000	IF DEB_EYE THEN  OUTSTR(" IN COMPARE -- VERTEX NUMBER = "&CVS(NVERT)&"
01100	         NUMBER OF LINES = "&CVS(VERTEX[NVERT,3])ACRLF);
01200		LINE1←VERTEX[NVERT,4];
01300		LINE2←VERTEX[NVERT,5];
01400		IF MODLINES=2 THEN
01500		BEGIN
01600			IF (FIT(LINE1,1)∧FIT(LINE2,2))
01700			  ∨(FIT(LINE2,1)∧FIT(LINE1,2)) THEN 
01800			RETURN(-1);
01900			GO TO FAIL;
02000		END;
02100		IF MODLINES=3 THEN
02200		BEGIN
02300			LINE3←VERTEX[NVERT,6];
02400			IF (FIT(LINE1,1)∧FIT(LINE2,2)∧FIT(LINE3,3))
02500			   ∨(FIT(LINE1,1)∧FIT(LINE3,2)∧FIT(LINE2,3))
02600			  ∨(FIT(LINE2,1)∧FIT(LINE1,2)∧FIT(LINE3,3))
02700		          ∨(FIT(LINE2,1)∧FIT(LINE3,2)∧FIT(LINE1,3))
02800			   ∨(FIT(LINE3,1)∧FIT(LINE1,2)∧FIT(LINE2,3))
02900			  ∨(FIT(LINE3,1)∧FIT(LINE2,2)∧FIT(LINE1,3)) THEN
03000			RETURN(-1);
03100			GO TO FAIL;
03200		END;
03300	FAIL:	IF NVERT>NVERTEX THEN RETURN(0);
03400		⊃ THIS IS USED FOR THE CASE OF TEST-VERTICIES;
03500	⊃ Now we destroy this vertex;
03600		FOR I←1 STEP 1 UNTIL MODLINES DO
03700		BEGIN
03800			K←VERTEX[NVERT,3+I];
03900	     		IF HUMPS[K,3]=NVERT THEN
04000			HUMPS[K,3]←HUMPS[K,13]←HUMPS[K,14]←-1
04100			ELSE IF HUMPS[K,4]=NVERT THEN 
04200			HUMPS[K,4]←HUMPS[K,15]←HUMPS[K,16]←-1;
04300		END;
04400		IF NVERT=NVERTEX THEN NVERTEX←NVERTEX-1 ELSE
04500		BEGIN
04600				VERTEX[NVERT,1]←-1000.;
04700				VERTEX[NVERT,2]←-1000.;
04800				VERTEX[NVERT,3]←0;
04900		END;
05000	       RETURN(0);
05100	END "PARE";
05200	
     

00100	
00200	SIMPLE PROCEDURE STORE_LINE(SHORT INTEGER N);
00300	⊃ Here we store the line data in array DIR_EYE;
00400	BEGIN "LSTOR"
00500	SHORT REAL XB,YB,XF,YF;
00600	SHORT INTEGER SIGX,SIGY;
00700	      		XB←HUMPS[N,FPOINT+1]; XF←HUMPS[N,HUMPS[N,6]+1];
00800			YB←HUMPS[N,FPOINT+2];YF←HUMPS[N,HUMPS[N,6]+2];
00900			SIGX←SIGN(XF-XB);
01000			SIGY←SIGN(YF-YB);
01100			DIR_EYE[0,1]←NCORNERS+1;
01200	           	DIR_EYE[NCORNERS,2]←(XB+XF)/2.;
01300			DIR_EYE[NCORNERS,3]←(YB+YF)/2.;
01400			DIR_EYE[NCORNERS,5]←HUMPS[N,THET];
01500	  		DIR_EYE[NCORNERS,6]←HUMPS[N,CEE];
01600			DIR_EYE[NCORNERS,7]←SIGX*ABS(HUMPS[N,SINTHETA]);
01700			DIR_EYE[NCORNERS,8]←SIGY*ABS(HUMPS[N,COSTHETA]);
01800			NCORNERS←NCORNERS+1;
01900	END "LSTOR";
02000	
02100	
02200	SIMPLE PROCEDURE STORE_CORN(SHORT INTEGER I,MODLINES);
02300	⊃ Here we store the corner data in array DIR_EYE;
02400	BEGIN "STOR"
02500	SHORT INTEGER K,J,KI,JI,NCT2,ZOR4;
02600	LABEL LAST1,LAST2;
02700		IF NCORNERS≥1 THEN
02800		FOR J←0 STEP 1 UNTIL NCORNERS-1 DO
02900		BEGIN
03000			NCT2←2*J;
03100			IF ABS(VERTEX[I,1]-DIR_EYE[NCT2,2])<DINT
03200			∧ABS(VERTEX[I,2]-DIR_EYE[NCT2,3])<DINT THEN
03300			BEGIN "LINEMATCH"
03400			FOR KI←1 STEP 1 UNTIL MODLINES DO 
03500			BEGIN
03600				IF KI=2 THEN 
03700				BEGIN
03800					ZOR4←0;
03900					NCT2←NCT2+1;
04000				END
04100				ELSE ZOR4←4;
04200				FOR K←1 STEP 1 UNTIL MODLINES DO
04300				BEGIN
04400					JI←VERTEX[I,3+K];
04500		IF ABS(HUMPS[JI,THET]-DIR_EYE[NCT2,ZOR4+1])<NDTH/2.
04600		∧ABS(HUMPS[JI,CEE]-DIR_EYE[NCT2,ZOR4+2])<NDC/2. THEN GO TO LAST1;
04700				END;
04800				GO TO LAST2;
04900		LAST1:	END;
05000			RETURN;
05100			END "LINEMATCH";
05200	LAST2:	END;
05300		NCT2←2*NCORNERS;
05400		NCORNERS←NCORNERS+1;
05500		IF EXT_LINE THEN DIR_EYE[0,1]←-1
05600		ELSE DIR_EYE[0,1]←NCORNERS;
05700		DIR_EYE[NCT2,2]←VERTEX[I,1];
05800		DIR_EYE[NCT2,3]←VERTEX[I,2];
05900		IF MODLINES=3 THEN DIR_EYE[NCT2,4]←VERTEX[I,VERTGAP];
06000		FOR K←1 STEP 1 UNTIL MODLINES DO
06100		BEGIN
06200			IF K=2 THEN 
06300			BEGIN 
06400				ZOR4←0;
06500				NCT2←NCT2+1;
06600			END
06700			ELSE ZOR4←4;
06800			J←VERTEX[I,3+K];
06900			DIR_EYE[NCT2,ZOR4+1]←HUMPS[J,THET];
07000			DIR_EYE[NCT2,ZOR4+2]←HUMPS[J,CEE];
07100			DIR_EYE[NCT2,ZOR4+3]←HUMPS[J,DIRSIN];
07200			DIR_EYE[NCT2,ZOR4+4]←HUMPS[J,DIRCOS];
07300		END;
07400		IF NCORNERS≥5 THEN WANT_ALL←0;
07500	
07600	END "STOR";
07700	
     

00100	
00200	
00300	PROCEDURE SET_FOR_SCAN(SHORT REAL XC,YC,DX,DY);
00400	⊃ Here we call for an edge_scan and line_find in a rectangular
00500		region. One end is centered about (XC,YC) and the
00600		rectangle points in the direction cos(α)=-DX, sin(α)=-DY;
00700	
00800	BEGIN "SETF"
00900	SHORT INTEGER YFIN, XCSAVE,YCSAVE;
01000	SHORT REAL X1,X2,X3,X4,Y1,Y2,Y3,Y4,XS1,XS2,YS1,YS2;
01100	SHORT REAL DTHSAVE,DCSAVE,DSSAVE,DGAPSAVE,ALPHA,DALPH;
01200	LABEL AFRECT,RESTORE;
01300	
01400	
01500	
01600		ALPHA←ATAN(DY/DX)+PIO2;
01700		DALPH←ABS(ACOS(1.-TOLER));
01800	IF DEB_EYE THEN 
01900		BEGIN 
02000			OUTSTR(" IN SET_FOR_SCAN "&CRLF);
02100			PRINT(ALPHA);
02200			PRINT(DALPH);
02300		END;
02400		X1←XC-5.*DY;
02500	  	Y1←YC+5.*DX;
02600		X2←X1-15.*DX+10.*DY;
02700		Y2←Y1-15.*DY-10.*DX;
02800		X3←X1-15.*DX;
02900		Y3←Y1-15.*DY;
03000		Y4←Y1-10.*DX;
03100		X4←X1+10.*DY;
03200	
03300	⊃ X1,Y1, X2,Y2, X3,Y3, X4,Y4  define the rotated rectangle;
03400	
03500		IF X1≤X2∧X1≤X3∧X1≤X4 THEN XS1←X1
03600		ELSE IF X2≤X3∧X2≤X4 THEN XS1←X2
03700		ELSE IF X3≤X4 THEN XS1←X3 ELSE XS1←X4;
03800		IF X1≥X2∧X1≥X3∧X1≥X4 THEN XS2←X1
03900		ELSE IF X2≥X3∧X2≥X4 THEN XS2←X2
04000		ELSE IF X3≥X4 THEN XS2←X3 ELSE XS2←X4;
04100		IF Y1≥Y2∧Y1≥Y3∧Y1≥Y4 THEN YS2←Y1
04200		ELSE IF Y2≥Y3∧Y2≥Y4 THEN YS2←Y2
04300		ELSE IF Y3≥Y4 THEN YS2←Y3 ELSE YS2←Y4;
04400		IF Y1≤Y2∧Y1≤Y3∧Y1≤Y4 THEN YS1←Y1
04500		ELSE IF Y2≤Y3∧Y2≤Y4 THEN YS1←Y2
04600		ELSE IF Y3≤Y4 THEN YS1←Y3 ELSE YS1←Y4;
04700		
04800	⊃	OUTSTR(" X1="&CVG(X1)&
04900		    "    Y1="&CVG(Y1)&
05000		    "    Y2="&CVG(Y2)&
05100		    "    X2="&CVG(X2)&
05200		    "    X3="&CVG(X3)&
05300		    "    Y3="&CVG(Y3)&
05400		    "    Y4="&CVG(Y4)&
05500		    "    X4="&CVG(X4)&CRLF);
05600	
05700	⊃ XS1,YS1, XS2,YS2, define the large rectangle which encloses
05800				the rotated rectangle;
05900		IF ¬DIS_EYE THEN GO TO AFRECT;
06000		AIVECT(TX(X1),TY(Y1));
06100		AVECT(TX(X3),TY(Y3));
06200		AVECT(TX(X2),TY(Y2));
06300		AVECT(TX(X4),TY(Y4));
06400		AVECT(TX(X1),TY(Y1));
06500		DPYOUT(1);
06600		IF CAL_COMP THEN CALCOMP("LOOKL",BUF);
06700	
06800	AFRECT:	XCSAVE←LOOK_AT[2];
06900		YCSAVE←LOOK_AT[3];
07000	
07100		LOOK_AT[2]←(XS1+XS2)/2;
07200		LOOK_AT[3]←(YS1+YS2)/2;
07300		LOOK_AT[5]←(YS2-YS1);
07400		LOOK_AT[4]←(XS2-XS1);
07500		DXY←(XS2+YS2)/SQ2;
07600		EXFLAG←0;
07700		GETPICTURE;
07800		IF DEB_EYE THEN 
07900		BEGIN DISPLAY; PRINT(LOOK_AT[6]); PRINT(LOOK_AT[7]); END;
08000		IF EXFLAG=10 THEN GO TO RESTORE;
08100		EJINIT; ⊃ This initializes edge operator;
08200	        YFIN←EDGE_SCAN(XC,YC,DX,DY); ⊃ Here we call the edge operator;
08300			DTHSAVE←NDTH;
08400			DCSAVE←NDC;
08500			DSSAVE←NDS;
08600			DGAPSAVE←NDGAP;
08700	             	NDTH←2*NDTH; ⊃ This makes it a little easier
08800					to find lines;
08900	             	NDC←2*NDC;
09000			NDS←10.;
09100			NDGAP←1.0;
09200	
09300		IF CAL_COMP THEN CAL2_COMP←-1;
09400	        GET_SOME_LINES(ALPHA,DALPH); ⊃ Here we call a line finder to
09500				to find lines with angle within DALPH of ALPHA;
09600	
09700	⊃ Now return all variables to their old values;
09800			CAL2_COMP←0;
09900			NDTH←DTHSAVE;
10000			NDC←DCSAVE;
10100			NDS←DSSAVE;
10200			NDGAP←DGAPSAVE;
10300	RESTORE:   LOOK_AT[2]←XCSAVE;
10400		LOOK_AT[3]←YCSAVE;
10500		LOOK_AT[4]←X_WIDTH;
10600		LOOK_AT[5]←Y_WIDTH;
10700	END "SETF";
10800	
     

00100	
00200	BOOLEAN PROCEDURE TWO_LINE_VERT(SHORT INTEGER N,J,MODLINES);
00300	
00400	⊃ Here we see if lines N and J fit the model and form
00500		a satisfactory vertex;
00600	
00700	BEGIN "TW"
00800	SHORT INTEGER K,L;
00900	REAL TEMP;
01000	LABEL AFT2;
01100	
01200		K←NVERTEX+1;
01300		INTERSECT(N,J);
01400		VERTEX[K,1]←X;
01500		VERTEX[K,2]←Y;
01600		VERTEX[K,3]←2;
01700		VERTEX[K,4]←N;
01800		VERTEX[K,5]←J;
01900		IF DIR_TEST(K) THEN GO TO AFT2; ⊃ Forget it
02000			at least one line does not fit;
02100		IF MODLINES=2 THEN IF ¬COMPARE(K) THEN GO TO AFT2; ⊃ Forget it;
02200		IF DEB_EYE THEN DIS_VERT(K);
02300		N2FOUND←N2FOUND+1;
02400		XX←X;
02500		YY←Y;
02600		IF EXT_LINE THEN TEMP←16. ELSE TEMP←4.;
02700		FOR L←N,J DO
02800		⊃ Testing for intersection inside of circle
02900		with slightly larger radius than usual;
03000		IF (X-HUMPS[L,HUMPS[L,VERT_END]+1])↑2
03100		+(Y-HUMPS[L,HUMPS[L,VERT_END]+2])↑2
03200		>TEMP*NDRADIUS*NDRADIUS THEN GO TO AFT2;
03300		NVERTEX←NVERTEX+1;
03400		FOR L←N,J DO
03500		⊃ We are satisfied so we make this a real vertex;
03600		IF HUMPS[L,VERT_END]=FPOINT THEN
03700		BEGIN
03800			HUMPS[L,3]←K;
03900			HUMPS[L,13]←X;
04000			HUMPS[L,14]←Y;
04100		END ELSE
04200		BEGIN
04300			HUMPS[L,4]←K;
04400			HUMPS[L,15]←X;
04500			HUMPS[L,16]←Y;
04600		END;
04700		IF DIS_EYE THEN SHOW_LINES;
04800		IF MODLINES=3 THEN RETURN(-1);
04900		IF CAL_COMP THEN CALCOMP("VERTEX",BUF);
05000		STORE_CORN(K,MODLINES);
05100		RETURN(-1);
05200	AFT2:	RETURN(0);
05300	END "TW";
05400	
05500	
05600	BOOLEAN PROCEDURE THREE_LINE_VERT(SHORT INTEGER N,J,L);
05700	
05800	⊃ Here we see if the three lines N,J, and L form a 
05900		satisfactory vertex;
06000	
06100	BEGIN "THREE"
06200	SHORT INTEGER K,NI;
06300	SHORT REAL VERT_GAP,TEMP;
06400	BOOLEAN TEST_GAP;
06500	LABEL AFT3;
06600	
06700		TEST_GAP←0;
06800		K← NVERTEX+1;
06900		IF EXT_LINE THEN TEMP←3. ELSE TEMP←1.5;
07000		NDACC←TEMP*NDACC;
07100		IF ¬VERT_THREE(N,J,L,X,Y,VERT_GAP) THEN
07200		BEGIN 
07300	⊃        	OUTSTR(CRLF&" VERTEX GAP = "&CVG(VERT_GAP));
07400			IF VERT_GAP<2.*NDACC THEN TEST_GAP←-1
07500			ELSE BEGIN NDACC←NDACC/TEMP; GO TO AFT3; END;
07600		END;
07700	⊃        	OUTSTR(CRLF&" VERTEX GAP = "&CVG(VERT_GAP));
07800		NDACC←NDACC/TEMP;
07900		VERTEX[K,1]←X;
08000		VERTEX[K,2]←Y;
08100		VERTEX[K,VERTGAP]←VERT_GAP;
08200		VERTEX[K,3]←MODLINES;
08300		VERTEX[K,4]←N;
08400		VERTEX[K,5]←J;
08500		VERTEX[K,6]←L;
08600		IF DIR_TEST(K) THEN GO TO AFT3; ⊃ At least one
08700			line does not fit;
08800		IF ¬COMPARE(K) THEN GO TO AFT3;
08900		IF DEB_EYE THEN DIS_VERT(K);
09000		N3FOUND←N3FOUND+1;
09100		XX←X;
09200		YY←Y;
09300		IF EXT_LINE THEN TEMP←16. ELSE TEMP←4.;
09400		FOR NI←N,J,L DO
09500		IF (X-HUMPS[NI,HUMPS[NI,VERT_END]+1])↑2
09600		+(Y-HUMPS[NI,HUMPS[NI,VERT_END]+2])↑2
09700		>TEMP*NDRADIUS*NDRADIUS THEN GO TO AFT3;
09800		IF TEST_GAP THEN GO TO AFT3;
09900		NVERTEX←NVERTEX+1; ⊃ Now we are satisfied
10000				so we make this a real vertex;
10100		FOR NI←N,J,L DO
10200		IF HUMPS[NI,VERT_END]=FPOINT THEN
10300		BEGIN
10400			HUMPS[NI,3]←K;
10500			HUMPS[NI,13]←X;
10600			HUMPS[NI,14]←Y;
10700		END ELSE
10800		BEGIN
10900			HUMPS[NI,4]←K;
11000			HUMPS[NI,15]←X;
11100			HUMPS[NI,16]←Y;
11200		END;
11300		IF DIS_EYE THEN SHOW_LINES;
11400		IF CAL_COMP THEN CALCOMP("VERTEX",BUF);
11500		STORE_CORN(K,MODLINES);
11600		RETURN(-1);
11700	AFT3:	RETURN(0);
11800	END "THREE";
11900	
12000	
     

00100	
00200	
00300	
00400		SHORT INTEGER DUM,F,J,K,L,N,TRN,SIGX,SIGY,LASTLINE,
00500		NUM_LINES,XFIN,YFIN,OTHER,OTHER2,WIDTH,HIGHT,NVERT,
00600	        NI,I,ISAVE,SGN,FEATS,MATS,MAXDIM,MINDIM,L1,L2;
00700		SHORT REAL MAX,MIN,TEMP,XC,YC;
00800		SHORT REAL DX,DY,EDG_TIM,LIN_TIM;
00900		LABEL RECNTR,FLINES,NEXT2,NEXT3,NEXT4,NEX2,NEX3;
01000		LABEL NEX4,NEX5,NEX6,DNEXT1;
01100		LABEL NEED2_VERT,NEED3_VERT,TEST2_VERT,TEST3_VERT,FOL2,FOL3;
01200		LABEL SUCCESS, FAILURE,FAIL_COMP,TWO_LINES,ABOVE;
01300		LABEL TRY_AGAIN,LAST2,LAST3,LAST4,FEW_LINES,DNEXT;
01400	
01500	
01600	
01700	
01800	    ⊃ Define the window;
01900	
02000		IF   LOOK_AT[4]>LOOK_AT[5]
02100		THEN BEGIN MINDIM←LOOK_AT[5]; MAXDIM←LOOK_AT[4]; END
02200		ELSE BEGIN MINDIM←LOOK_AT[4]; MAXDIM←LOOK_AT[5]; END;
02300		IF  (LOOK_AT[4]*LOOK_AT[5])>50000 THEN
02400		BEGIN 
02500		OUTSTR("FINDIMAG-FAILED: WINDOW TOO BIG FOR TVBUF (WIDTH="&
02600			          CVS(LOOK_AT[4])&"  HIGHT="&CVS(LOOK_AT[5])
02700							&")"ACRLF);
02800		           EXFLAG←10; RETURN;
02900		END;
03000		IF   MINDIM<5
03100		THEN BEGIN OUTSTR("FINDIMAG-FAILED: WINDOW TOO NARROW (MINDIM="&
03200				  CVS(MINDIM)&")"ACRLF);
03300		           EXFLAG←10; RETURN; END;
03400		WIDTH←LOOK_AT[4]; HIGHT←LOOK_AT[5];
03500	
03600	    ⊃ Accomodate, read in the window and display;
03700	
03800	RECNTR: 
03900		EXFLAG←0;  EXT_LINE←0; DIR_EYE[0,1]←0; N2FOUND←N3FOUND←0;
04000		  GETPICTURE;
04100		  IF EXFLAG=10 THEN GO TO FAIL_COMP;
04200		IF DIS_EYE THEN DISPLAY;
04300		EJINIT; ⊃ This initializes edge operator;
04400	
04500	TRY_AGAIN:	X1←LOOK_AT[2]-(LOOK_AT[4] DIV 2);
04600		X2←LOOK_AT[2]+(LOOK_AT[4] DIV 2);
04700		Y1←LOOK_AT[3]-(LOOK_AT[5] DIV 2);
04800		Y2←LOOK_AT[3]+(LOOK_AT[5] DIV 2);
04900		DXY←(X2+Y2)/SQ2;
05000	
05100		IF ¬DIS_EYE THEN EDG_TIM←CALL(0,"RUNTIM");
05200	FLINES:	YFIN←EDGE_FIND(X1,Y1,X2,Y2); ⊃ Call on the edge operator;
05300		IF ¬DIS_EYE THEN
05400		BEGIN
05500			LIN_TIM←CALL(0,"RUNTIM");
05600			EDG_TIM←(LIN_TIM-EDG_TIM)/1000.;
05700			PRINT(EDG_TIM);
05800		END;
05900	
06000		GET_LINES; ⊃ Call on the line finder;
06100		IF ¬DIS_EYE THEN
06200		BEGIN
06300			LIN_TIM←(CALL(0,"RUNTIM")-LIN_TIM)/1000.;
06400			PRINT(LIN_TIM);
06500		END;
06600		IF YFIN≠-1 THEN BEGIN Y1←YFIN; GO TO FLINES; ⊃ The edge
06700			array was too small so we have to go back; END;
06800	        IF TOLER<1 THEN ROUGH_COMPARE;
06900		IF NLINES=0 THEN GO TO FAIL_COMP;       
07000	
07100	
07200		⊃ LOOKING FOR 1 LINE;
07300		IF MODLINES =1 THEN
07400		BEGIN
07500	IF DEB_EYE THEN  OUTSTR("LOOKING FOR ONE LINE"ACRLF);
07600			IF NLINES=1 THEN BEGIN STORE_LINE(0); GO TO SUCCESS; END;
07700			IF ¬WANT_ALL THEN LASTLINE←1 ELSE
07800			BEGIN
07900				IF NLINES≤10 THEN LASTLINE←NLINES ELSE
08000				LASTLINE←10;
08100			END;
08200			MIN←2;
08300			FOR J←1 STEP 1 UNTIL LASTLINE DO
08400			BEGIN "ALL"
08500	          	MAX←0;
08600	         	FOR I←0 STEP 1 UNTIL NLINES-1 DO
08700			IF (TEMP←ABS(HUMPS[I,COSTHETA]*CORNMOD[1,COSTHETA]
08800			+HUMPS[I,SINTHETA]*CORNMOD[1,SINTHETA]))>MAX∧TEMP<MIN THEN
08900			BEGIN MAX←TEMP; ISAVE←I; END;
09000			MIN←MAX;
09100			STORE_LINE(ISAVE);
09200			END "ALL";
09300			GO TO SUCCESS;
09400		END;
09500	
09600	
09700		⊃ LOOKING FOR A SIMPLE CORNER;
09800		IF MODLINES =2 THEN 
09900		BEGIN "TWO"
10000	IF DEB_EYE THEN  OUTSTR(" LOOKING FOR SIMPLE CORNER"ACRLF);
10100			IF NLINES<MODLINES THEN GO TO FOL2;
10200			EXTEND; ⊃ Call on vertex former;
10300			IF NVERTEX=0 THEN GO TO NEED2_VERT;
10400	TEST2_VERT:     FOR I←1 STEP 1 UNTIL NVERTEX DO
10500			BEGIN "OUT"
10600				IF DEB_EYE THEN DIS_VERT(I);
10700				IF DIR_TEST(I)∧DEB_EYE THEN DIS_VERT(I);
10800				IF VERTEX[I,3]=MODLINES THEN TRY(I);
10900		NEXT2:	END "OUT";
11000	
11100	NEED2_VERT:	⊃ Here we form test vertices; N2FOUND←0;
11200			FOR N←0 STEP 1 UNTIL NLINES-2 DO
11300			FOR J←N+1 STEP 1 UNTIL NLINES-1 DO
11400			IF TWO_LINE_VERT(N,J,MODLINES)∧¬WANT_ALL THEN GO TO SUCCESS;
11500			IF EXT_LINE THEN GO TO FAIL_COMP;
11600			IF DEB_EYE∧N2FOUND>0 THEN 
11700	OUTSTR(" HAVE FOUND "&CVS(N2FOUND)&" COMBINATIONS THAT WORK,
11800		BUT NO VERTICIES WITH THESE COMBINATIONS! "ACRLF);
11900	
12000	FOL2:	IF TOLER≥1 THEN 
12100		BEGIN 
12200			IF DIR_EYE[0,1]=0 THEN GO TO FAIL_COMP
12300			ELSE GO TO SUCCESS;
12400		END;
12500		FOR K←0 STEP 1 UNTIL NLINES-1 DO
12600		BEGIN "FOLW2"
12700			IF HUMPS[K,3]>0∨HUMPS[K,4]>0 THEN GO TO LAST3;
12800	      		IF ABSFIT(K,1)∧¬ABSFIT(K,2) THEN
12900			BEGIN ISAVE←1; OTHER←2; GO TO NEX2; END;
13000			IF ABSFIT(K,2)∧¬ABSFIT(K,1) THEN
13100			BEGIN  ISAVE←2; OTHER←1; END  ELSE GO TO LAST2;
13200	NEX2:		SIGX←SIGN(CORNMOD[ISAVE,SINDIR]);
13300	       		SIGY←SIGN(CORNMOD[ISAVE,COSDIR]);
13400			FOLLOW[4]←SIGX*ABS(HUMPS[K,SINTHETA]);
13500			FOLLOW[5]←SIGY*ABS(HUMPS[K,COSTHETA]);
13600			FOLLOW[6]←HUMPS[K,CEE];
13700			IF ABS(HUMPS[K,SINTHETA])>0.5 THEN
13800			BEGIN
13900				IF SIGX=HUMPS[K,SIGNX] THEN I←HUMPS[K,6]
14000				ELSE I←FPOINT;
14100			END ELSE
14200			BEGIN 
14300				IF SIGY=HUMPS[K,SIGNY] THEN I←HUMPS[K,6]
14400				ELSE I←FPOINT;
14500			END;
14600			XC←HUMPS[K,I+1]+2.*FOLLOW[4];
14700			YC←HUMPS[K,I+2]+2.*FOLLOW[5];
14800			IF ABS(XC-LOOK_AT[2])<DELTA_X
14900			∧ABS(YC-LOOK_AT[3])<DELTA_Y THEN
15000			BEGIN
15100	IF DEB_EYE THEN OUTSTR(" HAVE FOUND THE END OF LINE "&CVS(K)
15200	&"  BUT NO CORNER"ACRLF);
15300				DX←CORNMOD[OTHER,SINDIR];
15400				DY←CORNMOD[OTHER,COSDIR];
15500				NUM_LINES←NLINES;
15600				SET_FOR_SCAN(XC,YC,DX,DY); ⊃ Here we look
15700						for a particular line;
15800				IF NUM_LINES=NLINES THEN GO TO DNEXT;
15900				FOR L←NUM_LINES STEP 1 UNTIL NLINES-1 DO
16000				IF ABSFIT(L,OTHER)∧TWO_LINE_VERT(L,K,MODLINES)
16100				∧¬WANT_ALL THEN GO TO SUCCESS;
16200				NLINES←NUM_LINES;
16300	DNEXT:			IF DIS_EYE THEN SHOW_LINES;
16400				GO TO LAST2;
16500			END;
16600			IF NLINES>1 THEN GO TO LAST2;
16700			FOLLOW[2]←HUMPS[K,I+1];
16800			FOLLOW[3]←HUMPS[K,I+2];
16900			EXFLAG←6;
17000			GO TO FAILURE;
17100	LAST2:	END "FOLW2";
17200		IF DIR_EYE[0,1]≠0 THEN GO TO SUCCESS;
17300		IF SEARCH≥1∨N2FOUND≠1 THEN GO TO FAIL_COMP;
17400		EXT_LINE←-1;
17500		GO TO NEED2_VERT;
17600		END "TWO";
17700	
17800	
17900	
18000		⊃ LOOKING FOR A PHYSICAL CORNER;
18100		IF MODLINES =3 THEN
18200		BEGIN
18300	 IF DEB_EYE THEN OUTSTR(" LOOKING FOR PHYSICAL CORNER "ACRLF);
18400			IF NLINES=1 THEN GO TO FOL3; 
18500			EXTEND; ⊃ Call on vertex former;
18600			IF NLINES=1 THEN GO TO FOL3;
18700			IF NLINES=2 THEN GO TO TWO_LINES;
18800			IF NVERTEX=0 THEN GO TO NEED3_VERT;
18900	TEST3_VERT:	FOR I←1 STEP 1 UNTIL NVERTEX DO
19000			BEGIN
19100				IF DEB_EYE THEN DIS_VERT(I);
19200				IF DIR_TEST(I)∧DEB_EYE THEN DIS_VERT(I);
19300				IF VERTEX[I,3]=MODLINES THEN TRY(I);
19400	 	NEXT3:	END;
19500		END;
19600	NEED3_VERT:	N3FOUND←0; 
19700			FOR N←0 STEP 1 UNTIL NLINES-3 DO
19800			FOR J←N+1 STEP 1 UNTIL NLINES-2 DO
19900			FOR L←J+1 STEP 1 UNTIL NLINES -1 DO
20000			IF THREE_LINE_VERT(L,J,N)∧¬WANT_ALL THEN GO TO SUCCESS;
20100			IF DEB_EYE∧N3FOUND>0 THEN 
20200	 OUTSTR(" HAVE FOUND "&CVS(N3FOUND)&" COMBINATIONS THAT WORK,
20300		BUT NO VERTICIES WITH THESE COMBINATIONS! "ACRLF);
20400	
20500	      	IF TOLER≥1 THEN 
20600		BEGIN 
20700			IF DIR_EYE[0,1]=0 THEN GO TO FAIL_COMP
20800			ELSE GO TO SUCCESS;
20900		END;
21000	TWO_LINES:	FOR N←0 STEP 1 UNTIL NLINES-2 DO
21100			BEGIN
21200				IF HUMPS[N,3]>0∨HUMPS[N,4]>0 THEN CONTINUE;
21300				FOR J←N+1 STEP 1 UNTIL NLINES-1 DO
21400				IF HUMPS[J,3]<0∧HUMPS[J,4]<0 THEN
21500				TWO_LINE_VERT(N,J,MODLINES);
21600			END;
21700	          	NVERT←NVERTEX;
21800	ABOVE:	FOR J←1 STEP 1 UNTIL NVERT DO
21900		BEGIN "TWOL"
22000		LABEL ONWARD;
22100	IF DEB_EYE THEN  
22200	OUTSTR(" LOOKING FOR A THIRD LINE IN TWO LINE VERTICIES"ACRLF);
22300	
22400			IF VERTEX[J,3]≠2 THEN CONTINUE;
22500	      		X←VERTEX[J,1];
22600			Y←VERTEX[J,2];
22700			IF ABS(X-LOOK_AT[2])>LOOK_AT[4]/2.
22800			∨ABS(Y-LOOK_AT[3])>LOOK_AT[5]/2. THEN GO TO FEW_LINES;
22900				IF ¬DEB_EYE THEN GO TO ONWARD;
23000	        	OUTSTR(" LOOKING AT VERTEX "&CVS(J)ACRLF);
23100			INCHWL;
23200			DIS_VERT(J);
23300	ONWARD:		IF DIR_TEST(J) THEN CONTINUE;
23400			N←VERTEX[J,4];
23500			NI←VERTEX[J,5];
23600			IF (L1←BESTFIT(N))∧(L2←BESTFIT(NI))∧L1≠L2 THEN
23700			FOR K←1 STEP 1 UNTIL MODLINES DO
23800			IF K≠L1∧K≠L2 THEN 
23900			BEGIN
24000				OTHER←K;
24100				GO TO NEXT4;
24200			END;
24300			GO TO LAST4;
24400	NEXT4: IF DEB_EYE THEN OUTSTR("HAVE FOUND TWO LINES MAKING A VERTEX 
24500			BUT CANNOT FIND THE THIRD LINE"ACRLF);
24600			NUM_LINES←NLINES;
24700			DX←CORNMOD[OTHER,SINDIR];
24800			DY←CORNMOD[OTHER,COSDIR];
24900			SET_FOR_SCAN(X,Y,DX,DY); ⊃ Here we look
25000				for a particular line;
25100			IF NUM_LINES=NLINES THEN GO TO DNEXT1;
25200			FOR L←NUM_LINES STEP 1 UNTIL NLINES-1 DO
25300			IF ABSFIT(L,OTHER)∧THREE_LINE_VERT(L,N,NI)
25400			∧¬WANT_ALL THEN GO TO SUCCESS;
25500			NLINES←NUM_LINES;
25600	DNEXT1:		IF DIS_EYE THEN SHOW_LINES;
25700			GO TO LAST4;
25800	FEW_LINES:	IF NLINES≥3 THEN GO TO LAST4;
25900			FOLLOW[2]←X;
26000			FOLLOW[3]←Y;
26100			EXFLAG←5;
26200			GO TO FAILURE;
26300	LAST4:	END "TWOL";
26400	FOL3:	IF TOLER≥1 THEN 
26500		BEGIN 
26600			IF DIR_EYE[0,1]=0 THEN GO TO FAIL_COMP
26700			ELSE GO TO SUCCESS;
26800		END;
26900		FOR K←0 STEP 1 UNTIL NLINES-1 DO
27000		BEGIN "FOLW3"
27100			IF HUMPS[K,3]>0∨HUMPS[K,4]>0 THEN GO TO LAST3;
27200	     		IF ABSFIT(K,1)∧¬ABSFIT(K,2)∧¬ABSFIT(K,3) THEN
27300			BEGIN ISAVE←1; GO TO NEX3; END;
27400			IF ABSFIT(K,2)∧¬ABSFIT(K,1)∧¬ABSFIT(K,3) THEN
27500			BEGIN ISAVE←2; GO TO NEX3; END;
27600			IF ABSFIT(K,3)∧¬ABSFIT(K,1)∧¬ABSFIT(K,2) THEN
27700			ISAVE←3 ELSE GO TO LAST3;
27800	NEX3:		SIGX←SIGN(CORNMOD[ISAVE,SINDIR]);
27900	       		SIGY←SIGN(CORNMOD[ISAVE,COSDIR]);
28000			FOLLOW[4]←SIGX*ABS(HUMPS[K,SINTHETA]);
28100			FOLLOW[5]←SIGY*ABS(HUMPS[K,COSTHETA]);
28200			FOLLOW[6]←HUMPS[K,CEE];
28300			IF ABS(HUMPS[K,SINTHETA])>0.5 THEN
28400			BEGIN
28500				IF SIGX=HUMPS[K,SIGNX] THEN I←HUMPS[K,6]
28600				ELSE I←FPOINT;
28700			END ELSE
28800			BEGIN 
28900				IF SIGY=HUMPS[K,SIGNY] THEN I←HUMPS[K,6]
29000				ELSE I←FPOINT;
29100			END;
29200			IF ISAVE=1 THEN BEGIN OTHER←2; OTHER2←3; END
29300			ELSE IF ISAVE=2 THEN BEGIN OTHER←1; OTHER2←3; END
29400			ELSE BEGIN OTHER←1; OTHER2←2; END;
29500			XC←HUMPS[K,I+1]+2.*FOLLOW[4];
29600			YC←HUMPS[K,I+2]+2.*FOLLOW[5];
29700			IF ABS(XC-LOOK_AT[2])<DELTA_X
29800			∧ABS(YC-LOOK_AT[3])<DELTA_Y THEN
29900			BEGIN
30000	⊃ OUTSTR(" HAVE FOUND THE END OF A LINE BUT NO CORNER"ACRLF);
30100				DX←CORNMOD[OTHER,SINDIR];
30200				DY←CORNMOD[OTHER,COSDIR];
30300				NUM_LINES←NLINES;
30400				SET_FOR_SCAN(XC,YC,DX,DY); ⊃ Here we look
30500					for one of the model lines;
30600				IF NUM_LINES=NLINES THEN GO TO NEX6;
30700				FOR L←NUM_LINES STEP 1 UNTIL NLINES-1 DO
30800				IF ABSFIT(L,OTHER) THEN GO TO NEX4;
30900				GO TO NEX6;
31000	NEX4:			DX←CORNMOD[OTHER2,SINDIR];
31100			        DY←CORNMOD[OTHER2,COSDIR];
31200				SET_FOR_SCAN(XC,YC,DX,DY); ⊃ Here we look
31300					for the other model line;
31400				IF NLINES<NUM_LINES+2 THEN GO TO NEX6;
31500				FOR L←NUM_LINES+1 STEP 1 UNTIL NLINES-1 DO
31600				IF ABSFIT(L,OTHER2) THEN GO TO NEX5;
31700				GO TO NEX6;
31800	NEX5:			FOR L←NUM_LINES STEP 1 UNTIL NLINES-2 DO
31900				FOR J←L+1 STEP 1 UNTIL NLINES-1 DO
32000				IF THREE_LINE_VERT(J,K,L)∧¬WANT_ALL THEN
32100				GO TO SUCCESS;
32200	NEX6:			NLINES←NUM_LINES;
32300				IF DIS_EYE THEN SHOW_LINES;
32400				GO TO LAST3;
32500			END;
32600			IF NLINES>1 THEN GO TO LAST3;
32700			FOLLOW[2]←HUMPS[K,I+1];
32800			FOLLOW[3]←HUMPS[K,I+2];
32900			EXFLAG←6;
33000			GO TO FAILURE;
33100	LAST3:	END "FOLW3";
33200		IF DIR_EYE[0,1]≠0 THEN GO TO SUCCESS;
33300		IF EXT_LINE∨SEARCH≥1∨N3FOUND≠1 THEN GO TO FAIL_COMP;
33400		EXT_LINE←-1;
33500		GO TO NEED3_VERT;
33600	
33700	
33800	
33900	
34000	SUCCESS:	OUTSTR("FINDIMAG SUCCEEDED:    "ACRLF);
34100			EXFLAG←0;
34200			RETURN;
34300	
34400	
34500	FAIL_COMP: EXFLAG←10;
34600	FAILURE:  DIR_EYE[0,1]←0;
34700		OUTSTR("FINDIMAG-FAILED:" &"NO MATCHES FOUND"ACRLF
34800			&"NUMBER OF LINES = "&CVS(NLINES)&
34900			",   VERTICES = "&CVS(NVERTEX)ACRLF);	
35000	 END "FINDIMAG";
     

00100	PROCEDURE SRCHIMAG(INTEGER MODLINES,DIREC,SEARCH; 
00200			REAL TOLER; REAL ARRAY CORNMOD);
00300	
00400	
00500	⊃ Here we direct the search space by moving the window if
00600		search is >0. Otherwise we just call on FINDIMAG;
00700	
00800	
00900	
01000	BEGIN "SRCHIMAG"
01100	
01200	
01300		SHORT INTEGER N,K,LSB,RSB,FLB,LLB,HWIDTH,HHIGHT,NCEN;
01400		SHORT INTEGER XIC0,YIC0,HDIM,J,L,LINE1,MODL,NCT2,ZOR4;
01500		SHORT REAL F, LENG, LO2,SINTH,COSTH,XP,YP;
01600		STRING CALSTR;
01700		LABEL PRINTR,OUT_DISP,AFT1;
01800	
01900	DEFINE	XMIN ="LOOK_AT[2] - (LOOK_AT[4] DIV 2) -LSIDE",
02000		YMIN = "LOOK_AT[3] - (LOOK_AT[5] DIV 2) - FLINE",
02100		XMAX = "LOOK_AT[2] + (LOOK_AT[4] DIV 2) - RSIDE",
02200		YMAX = "LOOK_AT[3] + (LOOK_AT[5] DIV 2) - LLINE";
02300		⊃ These limits keep us from going off the disk picture;
02400	
02500	
02600	    DEFINE ADVANCE="LOOK_AT[2]←XIC0+J*HWIDTH; LOOK_AT[3]←YIC0+L*HHIGHT;
02700		IF XMIN<0 THEN LOOK_AT[2] ← LSIDE +(LOOK_AT[4] DIV 2);
02800		IF YMIN<0 THEN LOOK_AT[3] ← FLINE +(LOOK_AT[5] DIV 2);
02900		IF YMAX>0 THEN LOOK_AT[3] ← LLINE -(LOOK_AT[5] DIV 2);
03000		IF XMAX>0 THEN LOOK_AT[3] ← RSIDE -(LOOK_AT[4] DIV 2);
03100	
03200	                     EXFLAG←0; FINDIMAG(MODLINES,DIREC,1,TOLER,CORNMOD);
03300		             IF EXFLAG=0 THEN GO TO PRINTR; ⊃ Success;
03400			     IF EXFLAG=1 THEN RETURN; ⊃ Poor window;
03500			     IF EXFLAG=5 THEN CHECK_VERT; ⊃ A VERTEX LOCATION
03600					TO EXAMINE HAS BEEN FOUND;
03700			     IF EXFLAG=6 THEN FOL_ONE; ⊃ A LINE TO FOLLOW 
03800					HAS BEEN FOUND;	";
03900	
04000	PROCEDURE CHECK_VERT;
04100	
04200	⊃ Here we move the window to check a promising vertex location;
04300	
04400	BEGIN "CHECK"
04500	SHORT REAL X,Y;
04600	INTEGER J;
04700	LABEL FORGET_IT, FIRST;
04800	FIRST:	X←FOLLOW[2];
04900		Y←FOLLOW[3];
05000	      	FOR J←1 STEP 1 UNTIL INTS DO
05100		IF ABS(X-INTER[1,J])<DINT∧ABS(Y-INTER[2,J])<DINT THEN
05200		BEGIN
05300			OUTSTR(" HAVE SEEN THIS VERTEX BEFORE"ACRLF);
05400			GO TO FORGET_IT;
05500		END;
05600		IF ABS(X-LOOK_AT[2])>SEARCH*LOOK_AT[4]
05700		∨ABS(Y-LOOK_AT[3])>SEARCH*LOOK_AT[5] THEN
05800	FORGET_IT:	BEGIN EXFLAG←10; RETURN; END;
05900		OUTSTR(" MOVING WINDOW TO LOOK FOR A VERTEX AT
06000			 --  X="&CVG(X)&"  Y="&CVG(Y)ACRLF);
06100		INTS←INTS+1;
06200		LOOK_AT[2]←INTER[1,INTS]←X;
06300		LOOK_AT[3]←INTER[2,INTS]←Y;
06400		FINDIMAG(MODLINES,DIREC,1,TOLER,CORNMOD);
06500		IF EXFLAG=0 THEN GO TO PRINTR;
06600		IF EXFLAG=6 THEN GO TO FIRST;
06700	END "CHECK";
06800	
06900	PROCEDURE FOL_ONE;
07000	BEGIN "FOL"
07100	SHORT INTEGER D,JJ;
07200	SHORT REAL DX_LINE, DY_LINE,C_LINE,X_END,Y_END;
07300	BOOLEAN TEST;
07400	LABEL FIRST,SECOND;
07500	
07600	⊃ Following one line to find simple corner;
07700	
07800		TEST←0;
07900	FIRST:	X_END←FOLLOW[2];
08000		Y_END←FOLLOW[3];
08100		DX_LINE←LIN[1,LINS+1]←FOLLOW[4];
08200		DY_LINE←LIN[2,LINS+1]←FOLLOW[5];
08300		C_LINE←LIN[3,LINS+1]←FOLLOW[6];
08400	OUTSTR(" FOLLOWING A LINE  "ACRLF);
08500	IF DEB_EYE THEN OUTSTR(" DX OF LINE-FOUND = "&CVG(DX_LINE)&"
08600	         DY OF LINE-FOUND = "&CVG(DY_LINE)ACRLF);
08700		IF TEST THEN BEGIN LINS←LINS-1; GO TO SECOND; END;
08800		FOR JJ←1 STEP 1 UNTIL LINS DO
08900		IF ABS(DX_LINE-LIN[1,JJ])<NDTH/2.
09000	        ∧ABS(DY_LINE-LIN[2,JJ])<NDTH/2.
09100	        ∧ABS(C_LINE-LIN[3,JJ])<NDC/2. THEN
09200		BEGIN
09300			EXFLAG←10;
09400			OUTSTR(" HAVE FOLLOWED THIS LINE BEFORE"ACRLF);
09500			RETURN;
09600		END;
09700	SECOND:	IF ABS(X_END-LOOK_AT[2])>SEARCH*LOOK_AT[4]
09800		∨ABS(Y_END-LOOK_AT[3])>SEARCH*LOOK_AT[5] THEN
09900		BEGIN EXFLAG←10; RETURN; END;
10000	        LOOK_AT[2]← X_END+(LOOK_AT[4]/2.-8)*DX_LINE;
10100		LOOK_AT[3]← Y_END+(LOOK_AT[5]/2.-8)*DY_LINE;
10200		LINS←LINS+1;
10300		FINDIMAG(MODLINES,DIREC,1,TOLER,CORNMOD);
10400		IF EXFLAG=0 THEN GO TO PRINTR; ⊃ Have found corner;
10500		IF EXFLAG=6 THEN BEGIN TEST←-1;GO TO FIRST; END;
10600			⊃ Still following this line;	
10700		IF EXFLAG=10 THEN RETURN; ⊃ Failure;
10800		IF EXFLAG=5 THEN CHECK_VERT; ⊃ Found a possible vertex 
10900						location to check;
11000		IF EXFLAG=0 THEN GO TO PRINTR; ⊃ Have found corner;
11100	END "FOL";
11200	
11300	
11400		INTS←LINS←0;
11500		IF TOLER≤0 THEN TOLER←1.;
11600		IF SEARCH≤0 THEN 
11700		BEGIN 
11800			FINDIMAG(MODLINES,DIREC,SEARCH,TOLER,CORNMOD); 
11900			IF EXFLAG=0 THEN GO TO PRINTR;
12000			RETURN;
12100		 END;
12200	
12300	    HWIDTH←LOOK_AT[4]-6; HHIGHT←LOOK_AT[5]-6; ⊃ We overlap window 
12400							by 6 units;
12500		 XIC0←LOOK_AT[2]; YIC0←LOOK_AT[3];
12600	    IF (HDIM←HWIDTH)>HHIGHT THEN HDIM←HHIGHT;
12700	    LSB←XIC0-SEARCH*HWIDTH; RSB←XIC0+SEARCH*HWIDTH;
12800	    FLB←YIC0-SEARCH*HWIDTH; LLB←YIC0+SEARCH*HWIDTH;
12900	    J←L←0; ADVANCE;
13000	
13100	    ⊃ Search;
13200	
13300	    FOR K←1 STEP 1 UNTIL SEARCH DO BEGIN
13400	    L←-K; FOR J←-K   STEP 1  UNTIL K    DO BEGIN ADVANCE END;
13500	    J←K;  FOR L←-K+1 STEP 1  UNTIL K    DO BEGIN ADVANCE END;
13600	    L←K;  FOR J←K-1  STEP -1 UNTIL -K   DO BEGIN ADVANCE END;
13700	    J←-K; FOR L←K-1  STEP -1 UNTIL -K+1 DO BEGIN ADVANCE END;
13800					   END;
13900	    OUTSTR("SRCHIMAG-FAILED: NOTHING FOUND IN SEARCH SPACE"ACRLF); RETURN;
14000	
14100	
14200	
14300	
14400	PRINTR:  IF DIS_EYE THEN 
14500		BEGIN "DIS"
14600			LENG←SMALLER(15.,SQRT(LOOK_AT[4]*LOOK_AT[5])/2.);
14700			LO2←LENG/2;
14800	     		DPYSET(BUF);
14900			IF CAL_COMP THEN DPYBIG(6);
15000			BOUNDARY(X1,Y2,X2,Y1);
15100		FOR N←1 STEP 1 UNTIL NCORNERS DO
15200		BEGIN
15300			NCEN←NCT2←2*(N-1);
15400			IF MODLINES=1 THEN NCT2←N-1;
15500			IF ¬DEB_EYE THEN GO TO AFT1;
15600			IF MODLINES=1 THEN 
15700			OUTSTR("X-CENTER AT "&CVG(DIR_EYE[N-1,2])&
15800			   ",   Y-CEMTER AT "&CVG(DIR_EYE[N-1,3])ACRLF)
15900			ELSE OUTSTR("X-VERTEX AT "&CVG(DIR_EYE[NCT2,2])&
16000			   ",   Y-VERTEX AT "&CVG(DIR_EYE[NCT2,3])ACRLF);
16100	AFT1:		AIVECT(-500,250);
16200	      		IF DIR_EYE[0,1]=-1 THEN 
16300			DPYSST(" POSSIBLE CORNER")
16400			ELSE IF MODLINES>1 THEN 
16500			BEGIN
16600				IF NCORNERS=1 THEN 
16700				CALSTR←CVS(NCORNERS)&" CORNER FOUND"
16800				ELSE CALSTR←CVS(NCORNERS)&" CORNERS FOUND";
16900	     			DPYSST(" "&CALSTR);
17000			END ELSE
17100			BEGIN
17200				IF NCORNERS=1 THEN 
17300				CALSTR←CVS(NCORNERS)&" LINE FOUND"
17400				ELSE CALSTR←CVS(NCORNERS)&" LINES FOUND";
17500	     			DPYSST(" "&CALSTR);
17600			END;
17700	
17800			FOR K←1 STEP 1 UNTIL MODLINES DO
17900			BEGIN
18000				IF K=2 THEN 
18100				BEGIN 
18200					ZOR4←0;
18300					NCT2←NCT2+1;
18400				END
18500				ELSE ZOR4←4;
18600				IF DEB_EYE THEN 
18700				BEGIN
18800	OUTSTR("TH-VALUE(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+1])ACRLF);
18900	OUTSTR("C-VALUE(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+2])ACRLF);
19000	OUTSTR(	"  SIN(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+3])ACRLF);
19100	OUTSTR(	"  COS(LINE "&CVS(K)&") = "&CVG(DIR_EYE[NCT2,ZOR4+4])ACRLF);
19200				END;
19300				IF MODLINES=1 THEN 
19400				BEGIN
19500			SINTH←SIN(DIR_EYE[N-1,5]);
19600			COSTH←COS(DIR_EYE[N-1,5]);
19700			ARROW(DIR_EYE[N-1,2],DIR_EYE[N-1,3],COSTH,SINTH);
19800			AIVECT(TX(DIR_EYE[N-1,2]-LO2*DIR_EYE[N-1,7]),
19900			       TY(DIR_EYE[N-1,3]-LO2*DIR_EYE[N-1,8]));
20000			AVECT(TX(DIR_EYE[N-1,2]+LO2*DIR_EYE[N-1,7]),
20100			       TY(DIR_EYE[N-1,3]+LO2*DIR_EYE[N-1,8]));
20200					GO TO OUT_DISP;
20300				END;
20400			COSTH←COS(DIR_EYE[NCT2,ZOR4+1]);
20500			SINTH←SIN(DIR_EYE[NCT2,ZOR4+1]);
20600			XP←DIR_EYE[NCEN,2]-LO2*DIR_EYE[NCT2,ZOR4+3];
20700			YP←DIR_EYE[NCEN,3]-LO2*DIR_EYE[NCT2,ZOR4+4];
20800			ARROW(XP,YP,COSTH,SINTH);
20900			AIVECT(TX(DIR_EYE[NCEN,2]),TY(DIR_EYE[NCEN,3]));
21000			AVECT(TX(DIR_EYE[NCEN,2]-LENG*DIR_EYE[NCT2,ZOR4+3]),
21100			   TY(DIR_EYE[NCEN,3]-LENG*DIR_EYE[NCT2,ZOR4+4]));
21200			END;
21300	OUT_DISP: END;
21400			DPYOUT(1);
21500			IF CAL_COMP THEN 
21600			BEGIN
21700				CALSTR←"CORN"&CVS(CORNERNUMBER);
21800				CALCOMP(CALSTR,BUF);
21900				CORNERNUMBER←CORNERNUMBER+1;
22000			END;
22100		END "DIS";
22200		RETURN;
22300	
22400	
22500		  OUTSTR("SRCHIMAG-FAILED: "ACRLF);
22600	  END "SRCHIMAG";
22700